--------------------------------------------------------------------------------
-- hlp_pps.lua
--   smartcard development help toolset for ISO7816 PPS information
--
-- y.volta ET gmail.com
-- 2011/05/29 17:58:52 
--------------------------------------------------------------------------------

help.PPS = {}

local s_iso7816_pps = [[

|PPSS| |PPS0| |PPS1|PPS2|PPS3| |PCK|

- PPSS: initial byte, must be 'FF'
- PPS0: format byte.
   | RFU|PPS3|PPS2|PPS1|        T       |
- PPS1: TA
- PPS2: TB
- PPS3: RFU
- PCK : XOR (PPSS, ... PCK) = 0
]]

setmetatable(help.PPS, 
{__tostring = function () return s_iso7816_pps; end }
)

tbl_fi = {
	372, 372, 558, 744, 1116,
	1488, 1860, 0,  0,  512,
	768, 1024, 1536, 2048, 
};

tbl_di = {0, 1, 2, 4, 8, 16, 32, 64, 12, 20, 0, 0, 0, 0, 0, 0};

-------------------------------------------------------------------------------
--  Fi table, from ISO7816-3
--[[
+---------------------------------------------------------------+
| B8-B5 | 0000 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 |
|  Fi   |  372 |  372 |  558 |  744 | 1116 | 1488 | 1860 |  --  |
|   f   |    4 |    5 |   6  |    8 |   12 |   16 |   20 |  --  |

| B8-B5 | 1000 | 1001 | 1010 | 1011 | 1100 | 1101 | 1110 | 1111 |
|  Fi   |  --  |  512 | 768  | 1024 | 1536 | 2048 |  --  |  --  |
|   f   |  --  |    5 |  7,5 |   10 |   15 |   20 |  --  |  --  |

   Di table, from ISO7816-3
+---------------------------------------------------------------+
| B4-B1 | 0000 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 |
|  Di   |  --  |    1 |    2 |    4 |    8 |   16 |   32 |   64 |

| B4-B1 | 1000 | 1001 | 1010 | 1011 | 1100 | 1101 | 1110 | 1111 |
|  Di   |   12 |   20 |  --  |  --  |  --  |  --  |  --  |  --  |
--]]


-- etu
function help.PPS.calc_etu (n_pps1)

  if type(n_pps1) ~= "number" then
    print ("pps1 should be number");
    return;
  end
  
  Di = bit.AND(n_pps1, 0x0F);
  Fi = bit.SHR(n_pps1, 4);
  
  etu = 0;
	ufi = 0;
  udi = 0;
  
	if (Fi == 0x07) or (Fi == 0x08) or (Fi == 0x0E) or (Fi == 0x0F) then
  
		print ("invalid Fi");
    return;
  end
  
	if (Di == 0x00) or (Di >= 0x0A) then
    print ("invalid Di")
		return 0;
  end
  
	ufi = tbl_fi[Fi+1];   -- lua table is 1 based, not 0
	udi = tbl_di[Di+1];   -- likewise
	
	etu = ( ufi + udi - 1 ) / udi;

	print ("etu= " .. etu);  
end

return help.PPS;
